#include<stdio.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<stdlib.h>
#include<unistd.h>

#define TASK_NUM 5

typedef void(*task_t)();

////////////////////////////////////////////////// 
void download()
{
    printf("This is a download task!\n");
}
void printfLog()
{
    printf("This is a printfLog task!\n");
}
void show()
{
    printf("This is a show task!\n");
}
////////////////////////////////////////////////// 
void initTasks(task_t tasks[],int num)
{
    for(int i = 0; i < num; i++)
    {
        tasks[i] = NULL;
    }
}

int addTask(task_t tasks[],task_t t)
{
    for(int i = 0; i < TASK_NUM; i++)
    {
        if(tasks[i] == NULL)
        {
            tasks[i] = t;
            return 1;
        }
    }
    return 0;
}

void executeTasks(task_t tasks[],int num)
{
    for(int i = 0; i < num; i++)
    {
        if(tasks[i])
        {
            tasks[i]();
        }
    }
}

void Work(int cnt)
{
    printf("I am %d child , pid: %d\n ",cnt,getpid());
}

int main()
{
    task_t tasks[TASK_NUM];
    initTasks(tasks,TASK_NUM);
    addTask(tasks,download);
    addTask(tasks,printfLog);
    addTask(tasks,show);
    pid_t id = fork();
    if(id == 0)
    {
        //child
        int cnt = 5;
        while(cnt--)
        {
            Work(cnt);
            sleep(2);
        }
        exit(0);
    }
        //parent
        while(1)
        {
            int status = 0;
            pid_t rid = waitpid(id,&status,WNOHANG);
            if(rid > 0)
            {
                //wait success,child quit now
                printf("child quit success,exit code: %d, exit signal: %d\n",(status>>8 & 0xFF),status&0x7F);
                break;

            }
            else if(rid == 0)
            {
                //wait success,but child not quit
                printf("child is alive,wait again,father do other thing.....\n");
                executeTasks(tasks,TASK_NUM);

            }
            else 
            {
                //wait faild,child unknow
                printf("wait faild!\n");
                break;
            }
            sleep(1);
        }
    
    
    return 0;
}
